<template>
    <Select class="common-component-select_dict" :value="selectedValue" filterable v-bind="$attrs" v-on="$listeners" @on-change="selectChangeHandler">
        <slot name="before"/>

        <template v-if="$isNotEmpty($scopedSlots.default)">
            <template v-if="arraySource">
                <Option v-if="showSelectAll" :value="selectAllValue">{{selectAllLabel}}</Option>
                <slot v-for="item in dictData" :label="item[labelField]" :value="item[keyField]" :disabled="selectAllFlag"/>
            </template>

            <template v-else>
                <Option v-if="showSelectAll" :value="selectAllValue">{{selectAllLabel}}</Option>
                <slot v-for="(label, value) in dictData" :label="label" :value="value" :disabled="selectAllFlag"/>
            </template>
        </template>

        <template v-else>
            <template v-if="arraySource">
                <Option v-if="showSelectAll" :value="selectAllValue">{{selectAllLabel}}</Option>
                <Option v-for="item in dictData" :key="item[keyField]" :value="item[keyField]" :disabled="selectAllFlag">{{item[labelField]}}</Option>
            </template>

            <template v-else>
                <Option v-if="showSelectAll" :value="selectAllValue">{{selectAllLabel}}</Option>
                <Option v-for="(label, value) in dictData" :key="value" :value="value" :disabled="selectAllFlag">{{label}}</Option>
            </template>
        </template>

        <slot name="after"/>
    </Select>
</template>

<script>
    export default {
        name: 'SelectDict',

        props: {
            code: String,

            url: String,

            request: {
                type: Function,
                default (){
                    return this.$ajax.post(...arguments);
                }
            },

            params: Object,

            keyField: {
                type: String,
                default (){
                    return 'code';
                }
            },

            labelField: {
                type: String,
                default (){
                    return 'name';
                }
            },

            showSelectAll: Boolean,

            selectAllLabel: {
                type: String,
                default (){
                    return "选择全部";
                }
            },

            selectAllValue: {
                type: String,
                default (){
                    return 'all';
                }
            },

            value: {required: false}
        },

        data (){
            return {
                dictData: [],
                selectedValue: '',
                selectAllFlag: false
            }
        },

        computed: {
            arraySource (){
                return this.$typeEqual(this.dictData, Array);
            }
        },

        created() {
            this.initQuery();
        },

        methods: {
            initQuery (){
                let req;

                if(this.url){
                    req = this.request(this.url, this.params);
                }else{
                    req = this.$api('dict', 'loadByParentCode', {code: this.code});
                }

                req.then(response => {
                    this.$set(this, 'dictData', response.data || []);
                });
            },

            selectChangeHandler (value){
                if(this.showSelectAll){
                    if(this.$isNotEmpty(value)){
                        if(!this.$typeEqual(value, Array)){
                            value = [value];
                        }

                        if(value.includes(this.selectAllValue)){
                            value = ('multiple' in this.$attrs || this.$attrs.multiple) ? [this.selectAllValue] : this.selectAllValue;

                            this.selectAllFlag = true;
                        }else{
                            this.selectAllFlag = false;
                        }
                    }else{
                        this.selectAllFlag = false;
                    }
                }

                this.$emit('input', value);

                let parent = this.$parent || this.$root;
                let name = parent.$options.name;

                while (parent && (!name || name !== 'FormItem')) {
                    parent = parent.$parent;

                    if (parent) {
                        name = parent.$options.name;
                    }
                }
                if (parent) {
                    parent.$emit.apply(parent, ['on-form-change'].concat(value));
                }
            }
        },

        watch: {
            value: {
                immediate: true,
                handler (v){
                    this.selectedValue = v;
                }
            }
        }
    }
</script>

<style lang="scss">
    .common-component-select_dict {
    }
</style>
